package fluo.rtp;

//RTPpacket.java
//Source Skeleton found from: http://www.csee.umbc.edu/~pmundur/courses/CMSC691C/RTPpacket.html
//Modified by Maher Beg, Prudhvi Tella, and Alex Bednarczyk

//class RTPpacket

public class RTPpacket{

      //size of the RTP header:
      static int HEADER_SIZE = 12;
      public static int PT_TYPE_MP3 = 14; //http://www.networksorcery.com/enp/protocol/rtp.htm (MPA RFC 2250, RFC 3551)

      //Fields that compose the RTP header
      public int Version;
      public int Padding;
      public int Extension;
      public int CC;
      public int Marker;
      public int PayloadType;
      public int SequenceNumber;
      public int TimeStamp;
      public int Ssrc;

      //Bitstream of the RTP header
      public byte[] header;

      //size of the RTP payload
      public int payload_size;
      //Bitstream of the RTP payload
      public byte[] payload;



      //--------------------------
      //Constructor of an RTPpacket object from header fields and payload bitstream
      //--------------------------
      public RTPpacket(int PType, int Framenb, int Time, byte[] data, int data_length){
              //fill by default header fields:
              Version = 2;
              Padding = 0;
              Extension = 0;
              CC = 0;
              Marker = 0;
              Ssrc = 0;

              //fill changing header fields:
              SequenceNumber = Framenb;
              TimeStamp = Time;
              PayloadType = PType;

              //build the header bistream:
              //--------------------------
              header = new byte[HEADER_SIZE];
              for(int i=0; i < HEADER_SIZE; i++) //initialize
                      header[i] = 0;
             
              //Source: http://www.networksorcery.com/enp/protocol/rtp.htm
              //version=2 bits, padding=1 bit, extension=1bit, CSRC count=4bits
              header[0] = (byte)((Version << 6) + (Padding << 5) + (Extension << 4) + CC); //should equal 128 = 0x80
              //Marker=1 bit, Payload Type = 7 bits (14 for mp3)
              header[1] = (byte)((Marker << 7) +PayloadType&~0x80);
              //Sequence Number split over two bytes
              header[2] = (byte)((SequenceNumber & 0xFF00) >> 8);
              header[3] = (byte)((SequenceNumber&0xFF));
              //Timestamp = 32 bits
              header[4] = (byte)((TimeStamp >> 24)&0xFF); header[5]=(byte)((TimeStamp >> 16)&0xFF);
              header[6] = (byte)((TimeStamp >> 8)&0xFF); header[7] = (byte)((TimeStamp)&0xFF);

              //fill the payload bitstream:
              //--------------------------
              payload_size = data_length;
              payload = new byte[data_length];
              for(int i=0; i < data_length; i++){
                      payload[i] = data[i];
              }
             

              // ! Do not forget to uncomment method printheader() below !

      }

      //--------------------------
      //Constructor of an RTPpacket object from the packet bistream
      //--------------------------
      public RTPpacket(byte[] packet, int packet_size)
      {
              //fill default fields:
              Version = 2;
              Padding = 0;
              Extension = 0;
              CC = 0;
              Marker = 0;
              Ssrc = 0;

              //check if total packet size is lower than the header size
              if (packet_size >= HEADER_SIZE)
              {
                      //get the header bitsream:
                      header = new byte[HEADER_SIZE];
                      for (int i=0; i < HEADER_SIZE; i++)
                              header[i] = packet[i];

                      //get the payload bitstream:
                      payload_size = packet_size - HEADER_SIZE;
                      payload = new byte[payload_size];
                      for (int i=HEADER_SIZE; i < packet_size; i++)
                              payload[i-HEADER_SIZE] = packet[i];

                      //interpret the changing fields of the header:
                      PayloadType = header[1] & 127;
                      SequenceNumber = unsigned_int(header[3]) + 256*unsigned_int(header[2]);
                      TimeStamp = unsigned_int(header[7]) + 256*unsigned_int(header[6]) + 65536*unsigned_int(header[5]) + 16777216*unsigned_int(header[4]);
              }
      }
     
      private int unsigned_int(byte in){
              return (int)in & 0xFF;
      }

      //--------------------------
      //getpayload: return the payload bistream of the RTPpacket and its size
      //--------------------------
      public int getpayload(byte[] data) {

              for (int i=0; i < payload_size; i++)
                      data[i] = payload[i];

              return(payload_size);
      }

      //--------------------------
      //getpayload_length: return the length of the payload
      //--------------------------
      public int getpayload_length() {
              return(payload_size);
      }

      //--------------------------
      //getlength: return the total length of the RTP packet
      //--------------------------
      public int getlength() {
              return(payload_size + HEADER_SIZE);
      }

      //--------------------------
      //getpacket: returns the packet bitstream and its length
      //--------------------------
      public int getpacket(byte[] packet)
      {
              //construct the packet = header + payload
              for (int i=0; i < HEADER_SIZE; i++)
                      packet[i] = header[i];
              for (int i=0; i < payload_size; i++)
                      packet[i+HEADER_SIZE] = payload[i];

              //return total size of the packet
              return(payload_size + HEADER_SIZE);
      }

      //--------------------------
      //gettimestamp
      //--------------------------

      public int gettimestamp() {
              return(TimeStamp);
      }

      //--------------------------
      //getsequencenumber
      //--------------------------
      public int getsequencenumber() {
              return(SequenceNumber);
      }

      //--------------------------
      //getpayloadtype
      //--------------------------
      public int getpayloadtype() {
              return(PayloadType);
      }


      //--------------------------
      //print headers without the SSRC
      //--------------------------
      public void printheader()
      {
              //TO DO: uncomment
              /*
for (int i=0; i < (HEADER_SIZE-4); i++)
  {
      for (int j = 7; j>=0 ; j--)
        if (((1<= 0)
  return(nb);
else
  return(256+nb);*/
      }

}

